package com.xingjiejian.leetcode.easy;

/**
 * 9. 回文数
 * 判断一个整数是否是回文数。回文数是指正序（从左向右）和倒序（从右向左）读都是一样的整数。
 * 示例 1:
 *      输入: 121
 *      输出: true
 *
 * 示例 2:
 *      输入: -121
 *      输出: false
 *      解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
 *
 * 示例 3:
 *      输入: 10
 *      输出: false
 *      解释: 从右向左读, 为 01 。因此它不是一个回文数。
 *
 * @author XingJiejian
 * @date 2019/5/8 0008
 */
public class PalindromeNumber {
    /**
     * 解法一：
     * 数字转换为字符串，并检查字符串是否为回文
     * 但是，这需要额外的非常量空间来创建问题描述中所不允许的字符串。
     * @param x
     * @return
     */
    public boolean isPalindrome(int x) {
        String xString = String.valueOf(x);

        if(xString.equals(new StringBuilder(xString).reverse().toString())){
            return true;
        }
        return false;
    }

    /**
     * 解法二：不转换成字符串
     * 思路：
     *    将数字本身反转，然后将反转后的数字与原始数字进行比较，如果它们是相同的，那么这个数字就是回文。
     * 但是，如果反转后的数字大于Integer.MAX_VALUE，将遇到整数溢出问题。
     *    为了避免数字反转可能导致的溢出问题，为什么不考虑只反转Integer.MAX_VALUE数字的一半？毕竟，如果
     * 该数字是回文，其后半部分反转后应该与原始数字的前半部分相同。
     *    例如，输入 1221，我们可以将数字 “1221” 的后半部分从 “21” 反转为 “12”，并将其与前半部分 “12”
     * 进行比较，因为二者相同，我们得知数字 1221 是回文。
     *
     * @param x
     * @return
     */
    public boolean isPalindrome2(int x){
        //首先处理临界
        // 第一，负数不是回文数
        // 第二，如果数字的最后一位是 0，为了使该数字为回文，则其第一位数字也应该是 0，只有 0 满足这一属性
        if ( x < 0 || ( x %10==0 && x!=0) ){
            return false;
        }

        // 反转后半部分的数字
        // 对于数字 1221,执行1221 % 10，得到1
        // 要得到倒数第二位数字, 执行 1221 / 10 % 10 = 2
        // 把最后一位数字乘以 10，再加上倒数第二位数字，1 * 10 + 2 = 12，就得反转后的数字
        // 如果继续这个过程，可以将得到更多位数的反转数字
        int revertedNumber = 0;
        while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时，我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如，当输入为 12321 时，在 while 循环的末尾我们可以得到 x = 12，revertedNumber = 123，
        // 由于处于中位的数字不影响回文（它总是与自己相等），所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber/10;
    }
}
